import 'dart:convert';
import 'package:dio/dio.dart';
import 'base_entity.dart';

typedef NetSuccessCallback = Function(dynamic data);
typedef NetConvert<T> = T Function(dynamic data);
typedef NetSuccessCallbackT<T> = Function(BaseEntity entity, T data);
typedef NetFailureCallback = Function(int code, String msg);

/// 默认的错误
final BaseEntity _defaultErrorEntity = BaseEntity(
  Code.error.code,
  Code.error.msg,
  null,
);

/// 创建一个成功的结果
BaseEntity createSuccessEntity<T> (T? data) => BaseEntity(Code.success.code, '', data);

class HttpUtil {
  HttpUtil._();

  static final HttpUtil _singleton = HttpUtil._();

  static HttpUtil get instance => _singleton;

  late final Dio _dio;

  late NetFailureCallback defaultFailureCallback;

  /// 初始化Dio配置
  void init({
    required String baseUrl,
    required NetFailureCallback defaultFailureCallback,
    required Duration connectTimeout,
    required Duration receiveTimeout,
    required Duration sendTimeout,
    List<Interceptor>? interceptors,
  }) {
    this.defaultFailureCallback = defaultFailureCallback;
    final BaseOptions options = BaseOptions(
      connectTimeout: connectTimeout,
      receiveTimeout: receiveTimeout,
      sendTimeout: sendTimeout,

      // dio默认json解析，这里指定返回UTF8字符串，自己处理解析。（可也以自定义Transformer实现）
      responseType: ResponseType.plain,
      validateStatus: (_) {
        // 不使用http状态码判断状态，使用AdapterInterceptor来处理（适用于标准REST风格）
        return true;
      },
      baseUrl: baseUrl,
      // contentType: Headers.formUrlEncodedContentType, // 适用于post form表单提交
    );
    _dio = Dio(options);
    interceptors?.forEach((element) {
      _dio.interceptors.add(element);
    });
  }

  /// 通用的返回数据的处理
  Future request<T>({
    required Future<BaseEntity> request,
    NetConvert<T>? onConvert,
    required NetSuccessCallbackT<T> onSuccess,
    NetFailureCallback? onFailure,
  }) async {
    BaseEntity baseEntity = await request;
    if (baseEntity.isSuccess) {
      if (onConvert != null) {
        T data = onConvert(baseEntity.data);
        onSuccess(baseEntity, data);
      } else {
        onSuccess(baseEntity, baseEntity.data);
      }
    } else {
      if (onFailure == null) {
        defaultFailureCallback(
          baseEntity.code,
          baseEntity.info ?? Code.failure.msg,
        );
      } else {
        onFailure(baseEntity.code, baseEntity.info ?? Code.failure.msg);
      }
    }
  }

  /// 供外界调用 - GET
  Future<BaseEntity> get({required String url, Map<String, dynamic>? params}) {
    return _requestGet(
      url: url,
      params: params,
    ).onError((error, stackTrace) => _defaultErrorEntity);
  }

  /// 供外界调用 - POST
  Future<BaseEntity> post({required String url, dynamic params}) {
    return _requestPost(
      url: url,
      params: params,
    ).onError((error, stackTrace) => _defaultErrorEntity);
  }

  /// 发送请求
  Future<BaseEntity> _requestGet({
    required String url,
    Map<String, dynamic>? params,
  }) async {
    try {
      Response response = await _dio.get(url, queryParameters: params);
      final String data = response.data.toString();
      Map<String, dynamic> map = json.decode(data);
      return BaseEntity.fromJson(map);
    } catch (e) {
      return _defaultErrorEntity;
    }
  }

  /// 发送请求
  Future<BaseEntity> _requestPost({required String url, dynamic params}) async {
    try {
      Response response = await _dio.post(url, data: params);
      final String data = response.data.toString();
      Map<String, dynamic> map = json.decode(data);
      return BaseEntity.fromJson(map);
    } catch (e) {
      return _defaultErrorEntity;
    }
  }
}
